home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 12 / Example 12.6 / effect.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-16  |  15.0 KB  |  469 lines

  1. #include "effect.h"
  2.  
  3. //Global Effect variables
  4. ID3DXMesh *billboardMesh = NULL;
  5. D3DMATERIAL9 whiteMtrl;
  6. SHADER effectVertexShader, effectPixelShader;
  7. D3DXHANDLE effectMatW, effectMatVP, effectVCol;
  8. ID3DXSprite *sprite = NULL;
  9.  
  10. //Global Effect Textures
  11. IDirect3DTexture9* runesTexture = NULL;
  12. IDirect3DTexture9* cloudTexture = NULL;
  13. IDirect3DTexture9* fireballTexture = NULL;
  14. IDirect3DTexture9* lensflareTexture = NULL;
  15.  
  16. struct SimpleVertex
  17. {
  18.     SimpleVertex(){}
  19.     SimpleVertex(D3DXVECTOR3 pos, D3DXVECTOR3 norm, D3DXVECTOR2 _uv)
  20.     {
  21.         m_position = pos;
  22.         normal = norm;
  23.         uv = _uv;
  24.     }
  25.  
  26.     D3DXVECTOR3 m_position, normal;
  27.     D3DXVECTOR2 uv;
  28.  
  29.     static const DWORD FVF;
  30. };
  31.  
  32. const DWORD SimpleVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
  33.  
  34. void LoadEffectResources(IDirect3DDevice9 *m_pDevice)
  35. {
  36.     //Calculate sight mesh (a simple quad)
  37.     D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, SimpleVertex::FVF, m_pDevice, &billboardMesh);
  38.  
  39.     //Create 4 vertices
  40.     SimpleVertex* v = 0;
  41.     billboardMesh->LockVertexBuffer(0,(void**)&v);
  42.     v[0] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 0));
  43.     v[1] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 0));
  44.     v[2] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 1));
  45.     v[3] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 1));
  46.     billboardMesh->UnlockVertexBuffer();
  47.  
  48.     //Create 2 faces
  49.     WORD* indices = 0;
  50.     billboardMesh->LockIndexBuffer(0,(void**)&indices);    
  51.     indices[0] = 0; indices[1] = 1; indices[2] = 2;
  52.     indices[3] = 1; indices[4] = 3; indices[5] = 2;
  53.     billboardMesh->UnlockIndexBuffer();
  54.  
  55.     //Set Attributes for the 2 faces
  56.     DWORD *att = 0;
  57.     billboardMesh->LockAttributeBuffer(0,&att);
  58.     att[0] = 0; att[1] = 0;
  59.     billboardMesh->UnlockAttributeBuffer();
  60.  
  61.     //Sight MTRL
  62.     memset(&whiteMtrl, 0, sizeof(D3DMATERIAL9));
  63.     whiteMtrl.Diffuse = whiteMtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  64.  
  65.     //Load Shaders
  66.     effectVertexShader.Init(m_pDevice, "shaders/effect.vs", VERTEX_SHADER);
  67.     effectPixelShader.Init(m_pDevice, "shaders/effect.ps", PIXEL_SHADER);
  68.  
  69.     //Get constants
  70.     effectMatW = effectVertexShader.GetConstant("matW");
  71.     effectMatVP = effectVertexShader.GetConstant("matVP");
  72.     effectVCol = effectVertexShader.GetConstant("vertexColor");
  73.  
  74.     //Create Sprite
  75.     D3DXCreateSprite(m_pDevice, &sprite);
  76.  
  77.     //Load textures
  78.     D3DXCreateTextureFromFile(m_pDevice, "textures/runes.dds", &runesTexture);
  79.     D3DXCreateTextureFromFile(m_pDevice, "textures/cloud.dds", &cloudTexture);
  80.     D3DXCreateTextureFromFile(m_pDevice, "textures/fireball.dds", &fireballTexture);
  81.     D3DXCreateTextureFromFile(m_pDevice, "textures/lensflare.dds", &lensflareTexture);
  82. }
  83.  
  84. void UnloadEffectResources()
  85. {
  86.     if(billboardMesh)billboardMesh->Release();
  87.     billboardMesh = NULL;
  88.  
  89.     if(sprite)sprite->Release();
  90.     sprite = NULL;
  91.  
  92.     //Release textures
  93.     if(runesTexture)runesTexture->Release();
  94.     if(cloudTexture)cloudTexture->Release();
  95.     if(fireballTexture)fireballTexture->Release();
  96.     if(lensflareTexture)lensflareTexture->Release();
  97.  
  98.     runesTexture = NULL;
  99.     cloudTexture = NULL;
  100.     fireballTexture = NULL;
  101.     lensflareTexture = NULL;
  102. }
  103.  
  104. //////////////////////////////////////////////////////////////////////////////////////////////
  105. //                                TRANSFORM                                                    //
  106. //////////////////////////////////////////////////////////////////////////////////////////////
  107.  
  108. TRANSFORM::TRANSFORM(){ m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  109. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  110. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  111. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  112.  
  113. void TRANSFORM::Init(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  114. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  115. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  116.  
  117. D3DXMATRIX TRANSFORM::GetWorldMatrix()
  118. {
  119.     D3DXMATRIX p, r, s;
  120.     D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
  121.     D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
  122.     D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
  123.     D3DXMATRIX world = s * r * p;
  124.     return world;
  125. }
  126.  
  127. //////////////////////////////////////////////////////////////////////////////////////////////
  128. //                                EFFECTS    BASE CLASS                                            //
  129. //////////////////////////////////////////////////////////////////////////////////////////////
  130.  
  131. EFFECT::EFFECT(IDirect3DDevice9 *Dev)
  132. {
  133.     m_pDevice = Dev;
  134.     m_time = 0.0f;
  135.     m_color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);    //White
  136. }
  137.  
  138. void EFFECT::PreRender()
  139. {
  140.     //Enable alpha blending
  141.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  142.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  143.     m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  144.     m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  145.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
  146.     m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  147.     m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  148.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  149.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  150.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  151.  
  152.     //Set vertex shader variables
  153.     D3DXMATRIX view, proj;
  154.     m_pDevice->GetTransform(D3DTS_VIEW, &view);
  155.     m_pDevice->GetTransform(D3DTS_PROJECTION, &proj);
  156.     
  157.     effectVertexShader.SetMatrix(effectMatVP, view * proj);
  158.     effectVertexShader.SetVector4(effectVCol, m_color);
  159.  
  160.     //Set material
  161.     m_pDevice->SetMaterial(&whiteMtrl);
  162.  
  163.     //enable Shaders
  164.     effectVertexShader.Begin();
  165.     effectPixelShader.Begin();
  166. }
  167.  
  168. void EFFECT::PostRender()
  169. {
  170.     //Reset renderstates
  171.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
  172.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  173.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  174.  
  175.     //Disable shaders
  176.     effectVertexShader.End();
  177.     effectPixelShader.End();
  178. }
  179.  
  180. //////////////////////////////////////////////////////////////////////////////////////////////
  181. //                                EFFECTS    SPELL                                                //
  182. //////////////////////////////////////////////////////////////////////////////////////////////
  183.  
  184. EFFECT_SPELL::EFFECT_SPELL(IDirect3DDevice9 *Dev, D3DXVECTOR3 _pos) : EFFECT(Dev), m_t1(_pos, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.1f, 0.1f, 0.1f))
  185. {
  186.     m_t1.m_pos.y += 1.0f;
  187.     m_color = D3DXVECTOR4(rand()%1000 / 1000.0f, rand()%1000 / 1000.0f, rand()%1000 / 1000.0f, 0.0f);
  188.  
  189.     for(int i=0;i<10;i++)
  190.     {
  191.         float angle = i * (D3DX_PI / 5.0f);
  192.             
  193.         m_c[i].Init(_pos + D3DXVECTOR3(cos(angle) * 0.5f, 2.5f, sin(angle) * 0.5f),
  194.                   D3DXVECTOR3(D3DX_PI * 0.5f, angle, 0.0f),
  195.                   D3DXVECTOR3(4.0f, 4.0f, 6.0f));
  196.     }
  197. }
  198.  
  199. void EFFECT_SPELL::Update(float timeDelta)
  200. {
  201.     m_time += timeDelta;
  202.  
  203.     //Update Lower spinning quad...
  204.     m_t1.m_rot.y += timeDelta;
  205.  
  206.     //Update cloud
  207.     for(int i=0;i<10;i++)
  208.         m_c[i].m_rot.y -= timeDelta;
  209.  
  210.     //Update Spinning quad scale
  211.     if(m_time < 1.5f)m_t1.m_sca += D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 4.0f;
  212.     if(m_time > 4.5f)m_t1.m_sca -= D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 4.0f;
  213.  
  214.     //Calculate alpha
  215.     m_color.w = m_t1.m_sca.x / 6.0f;
  216. }
  217.  
  218. void EFFECT_SPELL::Render()
  219. {
  220.     PreRender();
  221.  
  222.     if(billboardMesh)
  223.     {
  224.         //Spinning quad
  225.         m_pDevice->SetTexture(0, runesTexture);
  226.         effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  227.         billboardMesh->DrawSubset(0);
  228.  
  229.         //Cloud
  230.         m_pDevice->SetTexture(0, cloudTexture);
  231.         for(int i=0;i<10;i++)
  232.         {
  233.             effectVertexShader.SetMatrix(effectMatW, m_c[i].GetWorldMatrix());
  234.             billboardMesh->DrawSubset(0);
  235.         }
  236.     }
  237.  
  238.     PostRender();
  239. }
  240.  
  241. bool EFFECT_SPELL::isDead()
  242. {
  243.     return m_t1.m_sca.x < 0.0f;
  244. }
  245.  
  246. //////////////////////////////////////////////////////////////////////////////////////////////
  247. //                                EFFECTS    FIREBALL                                            //
  248. //////////////////////////////////////////////////////////////////////////////////////////////
  249.  
  250. EFFECT_FIREBALL::EFFECT_FIREBALL(IDirect3DDevice9 *Dev, BONE *_src, D3DXVECTOR3 _dest) : EFFECT(Dev)
  251. {
  252.     m_pSrcBone = _src;
  253.     dest = _dest;
  254.     m_color.w = 0.01f;
  255.     m_prc = 0.0f;
  256.     m_speed = 22.0f;
  257.  
  258.     if(m_pSrcBone != NULL)
  259.     {
  260.         D3DXMATRIX mat = m_pSrcBone->CombinedTransformationMatrix;        
  261.         m_t1.Init(D3DXVECTOR3(mat(3,0), mat(3, 1), mat(3, 2)), D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.1f, 0.1f, 0.1f));
  262.     }
  263. }
  264.  
  265. void EFFECT_FIREBALL::Update(float timeDelta)
  266. {
  267.     m_t1.m_rot += D3DXVECTOR3(0.5f, 0.5f, 0.5f) * timeDelta;
  268.  
  269.     if(m_time < 1.0f && m_pSrcBone != NULL)        //Follow staff
  270.     {
  271.         m_time += timeDelta;
  272.         D3DXMATRIX mat = m_pSrcBone->CombinedTransformationMatrix;
  273.         m_t1.m_pos = D3DXVECTOR3(mat(3,0), mat(3, 1), mat(3, 2));        //Extract position from bone
  274.         m_t1.m_sca = D3DXVECTOR3(1.5f, 1.5f, 1.5f) * m_time;
  275.         m_color.w = m_time;
  276.  
  277.         if(m_time > 1.0f)
  278.         {
  279.             m_color.w = m_time * 0.5f;
  280.             origin = m_t1.m_pos;
  281.             m_length = D3DXVec3Length(&(origin - dest));
  282.         }
  283.     }
  284.     else if(m_prc < 1.0f)        //Fly towards target
  285.     {
  286.         m_prc += (m_speed * timeDelta) / m_length;
  287.         m_t1.m_pos = GetPosition(m_prc);
  288.     }
  289.     else                    //Explode
  290.     {
  291.         m_prc += (m_speed * timeDelta) / m_length;
  292.         m_t1.m_sca += D3DXVECTOR3(5.0f, 5.0f, 5.0f) * timeDelta;
  293.         m_color.w -= timeDelta * 0.5f;
  294.     }
  295. }
  296.  
  297. void EFFECT_FIREBALL::Render()
  298. {
  299.     PreRender();
  300.  
  301.     if(billboardMesh)
  302.     {
  303.         D3DXVECTOR3 orgRot = m_t1.m_rot;
  304.         D3DXVECTOR3 rotations[] = {D3DXVECTOR3(0.0f, 0.0f, 0.0f),
  305.                                    D3DXVECTOR3(D3DX_PI * 0.5f, 0.0f, 0.0f),
  306.                                    D3DXVECTOR3(0.0f, D3DX_PI * 0.5f, 0.0f),
  307.                                    D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)};
  308.  
  309.         D3DXVECTOR3 orgPos = m_t1.m_pos;
  310.         D3DXVECTOR3 positions[] = {m_t1.m_pos, 
  311.                                    GetPosition(m_prc - (1.5f / m_length)),
  312.                                    GetPosition(m_prc - (2.5f / m_length)),
  313.                                    GetPosition(m_prc - (3.25f / m_length)),
  314.                                    GetPosition(m_prc - (4.0f / m_length))};
  315.  
  316.         D3DXVECTOR3 orgSca = m_t1.m_sca;
  317.         D3DXVECTOR3 scales[] = {m_t1.m_sca, 
  318.                                 m_t1.m_sca * 0.8f,
  319.                                 m_t1.m_sca * 0.6f,
  320.                                 m_t1.m_sca * 0.4f,
  321.                                 m_t1.m_sca * 0.2f};
  322.     
  323.         m_pDevice->SetTexture(0, fireballTexture);
  324.         for(int t=0;t<5;t++)
  325.             for(int i=0;i<4;i++)
  326.             {
  327.                 m_t1.m_pos = positions[t];
  328.                 m_t1.m_rot = orgRot + rotations[i];
  329.                 m_t1.m_sca = scales[t];
  330.  
  331.                 effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  332.                 billboardMesh->DrawSubset(0);
  333.             }
  334.  
  335.         m_t1.m_pos = orgPos;
  336.         m_t1.m_rot = orgRot;
  337.         m_t1.m_sca = orgSca;
  338.     }
  339.  
  340.     PostRender();
  341. }
  342.  
  343. bool EFFECT_FIREBALL::isDead()
  344. {
  345.     return m_pSrcBone == NULL || m_color.w < 0.0f;
  346. }
  347.  
  348. D3DXVECTOR3 EFFECT_FIREBALL::GetPosition(float p)
  349. {
  350.     if(p < 0.0f)p = 0.0f;
  351.     if(p > 1.0f)p = 1.0f;
  352.  
  353.     D3DXVECTOR3 m_pos = origin * (1.0f - p) + dest * p;    //Lerp between origin and dest
  354.     m_pos.y += sin(p * D3DX_PI) * 3.0f;                        //Add Arc
  355.     return m_pos;
  356. }
  357.  
  358. //////////////////////////////////////////////////////////////////////////////////////////////
  359. //                                EFFECTS    LENSFLARE                                            //
  360. //////////////////////////////////////////////////////////////////////////////////////////////
  361.  
  362. EFFECT_LENSFLARE::EFFECT_LENSFLARE(IDirect3DDevice9 *Dev, int _type, D3DXVECTOR3 _position) : EFFECT(Dev)
  363. {
  364.     m_position = _position;
  365.     m_type = _type;
  366.     m_mainAlpha = 0.0f;
  367.     m_inScreen = false;
  368.  
  369.     //Add Flares
  370.     if(m_type == 0)    //Standard flare
  371.     {
  372.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.5f, 0.7f, 0));
  373.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 1.0f, 1.0f, 1));
  374.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 0.5f, 0.5f, 1.0f), 1.5f, 1.3f, 2));
  375.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), -0.5f, 0.8f, 3));
  376.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 0.4f, 1.0f, 4));
  377.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.75f, 1.0f, 5));
  378.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f), 1.8f, 1.2f, 6));
  379.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 2.1f, 0.5f, 4));
  380.     }
  381.     else if(m_type == 1)        //Some other flare etc...
  382.     {
  383.         //setup your own flare here...
  384.     }
  385. }
  386.  
  387. void EFFECT_LENSFLARE::Update(float timeDelta)
  388. {
  389.     if(m_inScreen)
  390.         m_mainAlpha += timeDelta * 3.0f;
  391.     else m_mainAlpha -= timeDelta * 3.0f;
  392.  
  393.     if(m_mainAlpha > 1.0f)m_mainAlpha = 1.0f;
  394.     if(m_mainAlpha < 0.0f)m_mainAlpha = 0.0f;
  395. }
  396.  
  397. void EFFECT_LENSFLARE::Render()
  398. {
  399.     if(sprite == NULL || lensflareTexture == NULL)return;
  400.  
  401.     RECT sourceRectangles[7] = {{0, 0, 128, 128},
  402.                                 {128, 0, 256, 128},
  403.                                 {0, 128, 128, 256},
  404.                                 {128, 128, 192, 192},
  405.                                 {192, 128, 256, 192},
  406.                                 {128, 192, 192, 256},
  407.                                 {192, 192, 256, 256}};
  408.  
  409.     //Calculate screen position of light source
  410.     D3DXVECTOR3 screenPos;
  411.     D3DVIEWPORT9 Viewport;
  412.     D3DXMATRIX Projection, View, World;
  413.     m_pDevice->GetViewport(&Viewport);
  414.     m_pDevice->GetTransform(D3DTS_VIEW, &View);
  415.     m_pDevice->GetTransform(D3DTS_PROJECTION, &Projection);
  416.     D3DXMatrixIdentity(&World);
  417.     D3DXVec3Project(&screenPos, &m_position, &Viewport, &Projection, &View, &World);
  418.  
  419.     //Get viewport
  420.     D3DVIEWPORT9 v;
  421.     m_pDevice->GetViewport(&v);
  422.  
  423.     //Check that light source is within or without the screen bounds
  424.     if(screenPos.x < 0 || screenPos.x > v.Width ||
  425.        screenPos.y < 0 || screenPos.y > v.Height || screenPos.z > 1.0f)
  426.         m_inScreen = false;
  427.     else m_inScreen = true;
  428.  
  429.     //Lensflares aren't visible so exit function...
  430.     if(m_mainAlpha <= 0.0f)return;
  431.     
  432.     //Calculate the ray from the screen center to the light source
  433.     D3DXVECTOR2 lightSource = D3DXVECTOR2(screenPos.x, screenPos.y);
  434.     D3DXVECTOR2 screenCenter = D3DXVECTOR2(v.Width * 0.5f, v.Height * 0.5f);
  435.     D3DXVECTOR2 ray = screenCenter - lightSource;
  436.  
  437.     //Draw the different flares
  438.     D3DXMATRIX sca;
  439.     sprite->Begin(D3DXSPRITE_ALPHABLEND);
  440.     for(int i=0;i<m_flares.size();i++)
  441.     {
  442.         //Calculate Flare position in screen coordinates
  443.         RECT r = sourceRectangles[m_flares[i].sourceFlare];
  444.         D3DXVECTOR2 offset = D3DXVECTOR2((r.right - r.left) / 2.0f, (r.bottom - r.top) / 2.0f) * m_flares[i].scale;
  445.         D3DXVECTOR2 flarePos = lightSource + ray * m_flares[i].place - offset;
  446.  
  447.         //Scale
  448.         D3DXMatrixScaling(&sca, m_flares[i].scale, m_flares[i].scale, 1.0f);
  449.  
  450.         //Calculate flare alpha
  451.         D3DXCOLOR m_color = m_flares[i].m_color;
  452.         float alpha = (D3DXVec2Length(&((flarePos + offset) - screenCenter)) + 150.0f) / (float)v.Height;
  453.         if(alpha > 1.0f)alpha = 1.0f;
  454.         m_color.a = alpha * m_mainAlpha * 1.5f;
  455.  
  456.         //Draw Flare
  457.         sprite->SetTransform(&sca);
  458.         sprite->Draw(lensflareTexture, &r, NULL, &D3DXVECTOR3(flarePos.x / m_flares[i].scale, flarePos.y / m_flares[i].scale, 0.0f), m_color);
  459.     }
  460.     sprite->End();
  461.  
  462.     D3DXMatrixIdentity(&sca);
  463.     sprite->SetTransform(&sca);
  464. }
  465.  
  466. bool EFFECT_LENSFLARE::isDead()
  467. {
  468.     return false;
  469. }